#include "StdAfx.h"
#include "rscj_fit_1.h"
#include <ctime>


rscj_fit_1::rscj_fit_1(void)
{
	this->param.resize(10);
	this->param.at(0).name="Rn";
	this->param.at(0).value=1.0;
	//this->param.at(0).grad_weight=1.0;
	this->param.at(1).name="Ic";
	this->param.at(1).value=1.0;
	//this->param.at(1).grad_weight=1.0;
	this->param.at(2).name="C";
	this->param.at(2).value=1.0;
	//this->param.at(2).grad_weight=1.0;
	this->param.at(3).name="Iac";
	this->param.at(3).value=0.0;
	//this->param.at(3).grad_weight=1.0;
	this->param.at(4).name="w";
	this->param.at(4).value=1.0;
	//this->param.at(4).grad_weight=1.0;
	this->param.at(5).name="gamma";
	this->param.at(5).value=0;
	//this->param.at(5).grad_weight=1.0;
	this->param.at(6).name="Iasy";
	this->param.at(6).value=0;
	//this->param.at(6).grad_weight=1.0;
	this->param.at(7).name="Iex";
	this->param.at(7).value=0;
	//this->param.at(7).grad_weight=1.0;
	this->param.at(8).name="Ic2";
	this->param.at(8).value=0;
	//this->param.at(8).grad_weight=1.0;
	this->param.at(9).name="delta phi";
	this->param.at(9).value=0;
	//this->param.at(9).grad_weight=1.0;
	for(int i=0;i<this->param.size();++i){
		this->param.at(i).fit=false;
	}
}


rscj_fit_1::~rscj_fit_1(void)
{
}

std::vector<double> rscj_fit_1:: f(){
	u_i uiobj= u_i(this->param.at(0).value,this->param.at(1).value,this->param.at(2).value,this->param.at(4).value);
	uiobj.setIac(this->param.at(3).value);
	uiobj.setDeltaI(this->xdata);
	uiobj.setIasy(this->param.at(6).value);
	uiobj.setIex(this->param.at(7).value);
	uiobj.setTemp(this->param.at(5).value);
	uiobj.setIc2(this->param.at(8).value);
	uiobj.setdphi(this->param.at(9).value);
	uiobj.start();
	uiobj.join();
	std::vector<double> temp;
	for(int i=0;i<uiobj.U.size();++i){
		temp.push_back(uiobj.U.at(i));
	}
	std::string tempstring=this->filename+".fit";
	uiobj.setfilename(tempstring);
	uiobj.write();
	uiobj.~u_i();

	return temp;
}


std::vector<std::vector<double> >rscj_fit_1::df(){
	std::vector<std::vector<double> > temp;
	
	std::vector<int> fit_index;
	for(int i=0;i<this->param.size();++i){
		if(this->param.at(i).fit==true){
			fit_index.push_back(i);
		}
	}
	
	std::vector<std::vector<fit_modul::parameter> > para_set;
	para_set.push_back(this->param);
	int k=0;
	for(int i=0;i<fit_index.size();++i){
		para_set.push_back(this->param);
		para_set.back().at(fit_index.at(i)).value=para_set.back().at(fit_index.at(i)).value+abs(para_set.back().at(fit_index.at(i)).value)*GSL_SQRT_DBL_EPSILON;
	}

	std::vector<u_i> uiobj;
	for(int i=0;i<para_set.size();++i){
		uiobj.push_back(u_i(para_set.at(i).at(0).value,para_set.at(i).at(1).value,para_set.at(i).at(2).value,para_set.at(i).at(4).value));
	
	uiobj.back().setIac(para_set.at(i).at(3).value);
	uiobj.back().setDeltaI(this->xdata);
	uiobj.back().setIasy(para_set.at(i).at(6).value);
	uiobj.back().setIex(para_set.at(i).at(7).value);
	uiobj.back().setTemp(para_set.at(i).at(5).value);
	uiobj.back().setIc2(para_set.at(i).at(8).value);
	uiobj.back().setdphi(para_set.at(i).at(9).value);
	}

	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).start();
	}

	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).join();
	}

	temp.resize(this->ydata.size());
	for(int i=0;i<this->ydata.size();++i){
		temp.at(i).resize(fit_index.size());
		for(int j=0;j<uiobj.size()-1;++j){
			temp.at(i).at(j)=(uiobj.at(j+1).U.at(i)-uiobj.at(0).U.at(i))/(abs(para_set.at(j+1).at(fit_index.at(j)).value)*GSL_SQRT_DBL_EPSILON);
		}
	}

	std::string tempstring=this->filename+".fit";
	uiobj.at(0).setfilename(tempstring);
	uiobj.at(0).write();
	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).~u_i();
	}
	uiobj.clear();
	uiobj.~vector();
	return temp;
}

fit_modul::vecma rscj_fit_1::fdf(){
	fit_modul::vecma fdftemp;

	std::vector<std::vector<double> > temp;
	
	std::vector<int> fit_index;
	for(int i=0;i<this->param.size();++i){
		if(this->param.at(i).fit==true){
			fit_index.push_back(i);
		}
	}
	
	std::vector<std::vector<fit_modul::parameter> > para_set;
	para_set.push_back(this->param);
	int k=0;
	for(int i=0;i<fit_index.size();++i){
		para_set.push_back(this->param);
		para_set.back().at(fit_index.at(i)).value=para_set.back().at(fit_index.at(i)).value+abs(para_set.back().at(fit_index.at(i)).value)*GSL_SQRT_DBL_EPSILON;
	}

	std::vector<u_i> uiobj;
	for(int i=0;i<para_set.size();++i){
		uiobj.push_back(u_i(para_set.at(i).at(0).value,para_set.at(i).at(1).value,para_set.at(i).at(2).value,para_set.at(i).at(4).value));
	
	uiobj.back().setIac(para_set.at(i).at(3).value);
	uiobj.back().setDeltaI(this->xdata);
	uiobj.back().setIasy(para_set.at(i).at(6).value);
	uiobj.back().setIex(para_set.at(i).at(7).value);
	uiobj.back().setTemp(para_set.at(i).at(5).value);
	uiobj.back().setIc2(para_set.at(i).at(8).value);
	uiobj.back().setdphi(para_set.at(i).at(9).value);
	}
	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).start();
	}

	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).join();
	}

	

	temp.resize(this->ydata.size());
	for(int i=0;i<this->ydata.size();++i){
		temp.at(i).resize(fit_index.size());
		for(int j=0;j<uiobj.size()-1;++j){
			temp.at(i).at(j)=(uiobj.at(j+1).U.at(i)-uiobj.at(0).U.at(i))/(abs(para_set.at(j+1).at(fit_index.at(j)).value)*GSL_SQRT_DBL_EPSILON);
		}
	}




	for(int i=0;i<uiobj.at(0).U.size();++i){
		fdftemp.f.push_back(uiobj.at(0).U.at(i));
	}
	std::string tempstring=this->filename+".fit";
	uiobj.at(0).setfilename(tempstring);
	uiobj.at(0).write();
	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).~u_i();
	}
	uiobj.clear();
	uiobj.~vector();
	
	
	fdftemp.df=temp;
	return fdftemp;
	
}